Force update to latest version


Posted by Limon on 2022-04-11

In the project, we need to force the app to be updated to the latest version when the user opens the app.The download source is not google play, but the website provided by the company.

Since we are not downloading from the google play store, we must have our own api to determine whether the current app version is the latest version.

For security, the code about the api will not be shown here.

AndroidManifest

The following permissions need to be enabled

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

The following properties need to be set in

android:requestLegacyExternalStorage="true"

After Android Nougat (API 24), file paths must be shared across apps through FileProvider. FileProvider will hide the actual path of the file, making file sharing more secure.

Declare androidx.core.content.FileProvider in AndroidManifest.xml

FileProvider

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${packageName}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_provider_paths" />
</provider>

xml/file_provider_paths is used to define which directories can be accessed by other apps.

<paths>
    <external-path path="Android/data/${packageName}/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>

AutoUpdateService

Create a service file and don't forget to declare it in AndroidManifest.xml

<service
    android:name=".AutoUpdateService"
    android:exported="false" />

When the service is started in the activity and the downloaded apk is detected, it will be automatically installed.

Implement AutoUpdateService.java

public class AutoUpdateService extends Service{
    private DownloadCompleteReceiver mReceiver;
    public static ServiceState serviceState = ServiceState.IDLE;
    public static enum ServiceState {
        RUNNING,
        IDLE
    }
    private long downloadCompleteId;

    public class DownloadCompleteReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            downloadCompleteId = intent.getLongExtra(DownloadManager.ACTION_DOWNLOAD_COMPLETE, -1);

            serviceState = ServiceState.IDLE;

            reInstallApp();

            stopSelf();

        }
    }
    @Override
    public void onCreate() {
        super.onCreate();
        mReceiver = new DownloadCompleteReceiver();
        registerReceiver(mReceiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        serviceState = ServiceState.IDLE;
        unregisterReceiver(mReceiver);
    }
    private void reInstallApp() {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        String apkFilePath = Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_DOWNLOADS + "/" + APKConfig.APK_NAME;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri contentUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileProvider", new File(apkFilePath));
            intent.setDataAndType(contentUri, APKConfig.INSTALL_APK_DATA_TYPE);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            intent.setDataAndType(Uri.fromFile(new File(apkFilePath)), APKConfig.INSTALL_APK_DATA_TYPE);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }

        startActivity(intent);
    }
}

#Android #force update







Related Posts

JS註冊組|學習筆記|JavaScript&jQuery網站互動設計程式進化之道

JS註冊組|學習筆記|JavaScript&jQuery網站互動設計程式進化之道

不用dynamic dns,使用ssh連上非固定IP的linux電腦

不用dynamic dns,使用ssh連上非固定IP的linux電腦

JQuery 筆記:You might not need JQuery doesn't mean you can't try it

JQuery 筆記:You might not need JQuery doesn't mean you can't try it


Comments